/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elsimulatorjava;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 *
 * @author corey
 */
public class Application extends JFrame implements ActionListener{
    
    private JTabbedPane tabBar;
    private FloorPanel floorUi;
    private JRadioButton[] floorOptions;
    private short floorSelected;
    
    private ElevatorPanel elevatorUi;
    private JPanel adminUi;
    
    private JScrollPane simScrollPane;
    private SimulationPanel simulationPanel;
    private JButton startButton;
    private JButton pauseButton;
    private JButton editButton;
    private JButton saveButton;
    private JButton loadButton;
    
    private JButton aEditFloorsButton;
    private JButton aEditElevatorsButton;
    private JTextField aNumOfFloorsLE;
    private JTextField aNumOfElevatorsLE;
    private JTextField aNumOfPeopleLE;
    
    private JSlider pplProbSlider;
    private JSlider speedSlider;
    
    private Timer timerSimUi;

    
    private Date elapsed = new Date();

    private Floor[] floors = new Floor[0];
    private Elevator[] elevators = new Elevator[0];
    private boolean pauseSimulation = false;
    
    private Building b;
    private Thread t;
    
    private FloorDialog floorDialog;
    private ElevatorDialog elevatorDialog;

    boolean paused;
    
    public Application(){
        this.setTitle("Yeroc elSimulator");
        this.setSize(800, 600);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        floorSelected = 0;
        
        //QValidator numbersOnly = new QIntValidator(0, 999, this);
        aEditFloorsButton = new JButton("Edit");
        aEditFloorsButton.addActionListener(new ActionListener() {
            
            public void actionPerformed(ActionEvent e)
            {
                
                Floor.resetCounter();
                if (!aNumOfFloorsLE.getText().isEmpty() && Integer.parseInt(aNumOfFloorsLE.getText()) > 1){
                    floorDialog = new FloorDialog(Short.parseShort(aNumOfFloorsLE.getText()));
                    floorDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                    floorDialog.addWindowListener(new WindowAdapter() {
                        @Override
                        public void windowClosed(WindowEvent we) {
                            floors = floorDialog.getFloors();
                        }
                    });
                    floorDialog.setVisible(true);
                    /*if (floorDialog.setVisible(true) == 0){
                        this.floors = floorDialog.getFloors();
                        //aNumOfElevatorsLE.setFocus();
                    }*/
                } else {
                    //MessageBox msgBox = new QMessageBox();
                    //msgBox.setText("At least two floors are required.");
                    //msgBox.setIcon(QMessageBox.Icon.Warning);
                    //msgBox.exec();
                }
                //elevators = new ArrayList<Elevator>();
                
            }
        }); 
        aEditElevatorsButton = new JButton("Edit");
        aEditElevatorsButton.addActionListener(new ActionListener() {
 
            public void actionPerformed(ActionEvent e)
            {
                Elevator.resetCounter();
                if (!aNumOfElevatorsLE.getText().isEmpty() && Integer.parseInt(aNumOfElevatorsLE.getText()) > 0){
                    elevatorDialog = new ElevatorDialog(Short.parseShort(aNumOfElevatorsLE.getText()), (short)(floors.length));
                    elevatorDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                    floorDialog.addWindowListener(new WindowAdapter() {
                        @Override
                        public void windowClosed(WindowEvent we) {
                            elevators = elevatorDialog.getElevators();
                        }
                    });
                    elevatorDialog.setVisible(true);
                }
            }
        }); 
        aNumOfFloorsLE = new JTextField("10");
        //aNumOfFloorsLE.setValidator(numbersOnly);
        //aNumOfFloorsLE.setAlignment(Qt.AlignmentFlag.AlignRight);
        aNumOfElevatorsLE = new JTextField();
        //aNumOfElevatorsLE.setValidator(numbersOnly);
        aNumOfFloorsLE.setSize(aNumOfFloorsLE.getHeight(), 300);
        aNumOfElevatorsLE.setSize(aNumOfElevatorsLE.getHeight(), 300);
        //aNumOfElevatorsLE.setAlignment(Qt.AlignmentFlag.AlignRight);
        aNumOfPeopleLE = new JTextField();
        //aNumOfPeopleLE.setValidator(numbersOnly);
        aNumOfPeopleLE.setSize(aNumOfPeopleLE.getHeight(), 300);
        //aNumOfPeopleLE.setAlignment(Qt.AlignmentFlag.AlignRight);
        //aNumOfFloorsLE.setText("0");
        aNumOfElevatorsLE.setText("1");
        
        pplProbSlider = new JSlider(0, 100);
        pplProbSlider.setMajorTickSpacing(10);
        pplProbSlider.setMinorTickSpacing(1);
        pplProbSlider.setPaintTicks(true);
        pplProbSlider.setPaintLabels(true);
        pplProbSlider.addChangeListener(new ChangeListener(){ 
            @Override
            public void stateChanged(ChangeEvent e){
                if (!pplProbSlider.getValueIsAdjusting() && !(b == null)){
                    
                    b.setPeopleProbability((byte)pplProbSlider.getValue());
                }
            }    
        });
        
        speedSlider = new JSlider(1, 101, 30);
        speedSlider.setMajorTickSpacing(10);
        speedSlider.setMinorTickSpacing(1);
        speedSlider.setPaintTicks(true);
        speedSlider.setPaintLabels(true);
        speedSlider.addChangeListener(new ChangeListener(){ 
            @Override
            public void stateChanged(ChangeEvent e){
                if (!speedSlider.getValueIsAdjusting() && !(b == null)){
                    timerSimUi.setDelay(speedSlider.getValue());
                }
            }    
        });
        
        pauseButton = new JButton("Pause Simulation");
        pauseButton.setEnabled(false);
        pauseButton.addActionListener(new ActionListener() {
 
            public void actionPerformed(ActionEvent e)
            {
                editButton.setEnabled(true);
                pauseSimulation = true;
                pauseButton.setEnabled(false);
                startButton.setEnabled(true);
                timerSimUi.stop();
            }
        }); 
        startButton = new JButton("Start Simulation");
        startButton.addActionListener(new ActionListener() {
 
            public void actionPerformed(ActionEvent e)
            {
                if (!(elevators.length > 0) && !(floors.length > 0)){
                    boolean[] bl = new boolean[10];
                    floors = new Floor[10];
                    for (int i = 0; i < 10; i++){
                        floors[i] = new Floor("Floor " + i);
                        bl[i] = true;
                    }
                    elevators = new Elevator[1];
                    elevators[0] = new Elevator((short)0,(short)9,(short)0, (byte)10, bl);
                }
                    pauseSimulation = false;
                    editButton.setEnabled(false);
                    
                    b = new Building(elevators, floors, (byte) pplProbSlider.getValue());
                try {
                    floorUi = new FloorPanel(b.getElevators(), b.getFloors());
                } catch (IOException ex) {
                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                }

                    try {
                        elevatorUi = new ElevatorPanel(elevators, (short)b.getNumberOfFloors(), new Dimension(780,550));
                    } catch (IOException ex) {
                        Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    simulationPanel = new SimulationPanel(b.getElevators(), b.getFloors(), tabBar.getSize());
                    simScrollPane = new JScrollPane(simulationPanel);
                    simScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
                    simScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
                    
                    
                    
                    timerSimUi = new Timer(speedSlider.getValue(), new ActionListener() {

                        public void actionPerformed(ActionEvent ae) {
                            if (!pauseSimulation){
                                b.run();
                                
                                try {
                                    switch (tabBar.getSelectedIndex()){
                                        case 1:
                                            simulationPanel.repaint();
                                            break;
                                        
                                        case 2:
                                            floorUi.updateFloors();
                                            break;
                                        
                                        case 3:
                                            elevatorUi.updateElevatorPanel();
                                            break;
                                    }
                                            //setElevatorPostitions(b.getElevatorPositions(), b.getDoorOpenings());
                                } catch (IOException ex) {
                                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                                }
                            }
                        }
                    });
                    timerSimUi.start();
                    setAdminFields(false);
                    startButton.setEnabled(false);
                    pauseButton.setEnabled(true);
                    saveButton.setEnabled(true);
                    loadButton.setEnabled(true);

                    if (tabBar.getTabCount() == 1){
                        tabBar.addTab("Simulation", simScrollPane);
                        tabBar.addTab("Floor", floorUi);
                        tabBar.addTab("Elevator", elevatorUi);
                        tabBar.setSelectedIndex(1);
                    } else {
                        System.out.println(tabBar.getTabCount());
                        tabBar.setComponentAt(1, simScrollPane);
                        tabBar.setComponentAt(2, floorUi);
                        tabBar.setComponentAt(3, elevatorUi);
                        tabBar.setSelectedIndex(1);
                    }
                    
                
                }
        }); 
        
        editButton = new JButton("Edit Simulation");
        editButton.setEnabled(false);
        editButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e){
                setAdminFields(true);
                tabBar.removeTabAt(1);
                tabBar.removeTabAt(1);
                tabBar.removeTabAt(1);
                editButton.setEnabled(false);
            }
        });

        tabBar = new JTabbedPane();

        adminUi = new JPanel();
        JPanel adminFormPanel = new JPanel();
        
        adminUi.setLayout(new BoxLayout(adminUi, BoxLayout.Y_AXIS));
        
        GridLayout formGridLayout = new GridLayout(0,3);
        formGridLayout.setHgap(30);
        formGridLayout.setVgap(0);
        adminFormPanel.setLayout(formGridLayout);
        adminFormPanel.add(new JLabel("Number of floors"));
        adminFormPanel.add(aNumOfFloorsLE);
        adminFormPanel.add(aEditFloorsButton);
        adminFormPanel.add(new JLabel("Number of elevators"));
        adminFormPanel.add(aNumOfElevatorsLE);
        adminFormPanel.add(aEditElevatorsButton);

        GridLayout buttonGridLayout = new GridLayout(3,2);
        JPanel adminButtonPanel = new JPanel();
        adminButtonPanel.setLayout(buttonGridLayout);
        saveButton = new JButton("Save");
        saveButton.setEnabled(false);
        saveButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                pauseSimulation = true;
                try {
                    b.save(b.getFloors(), b.getElevators());
                } catch (Exception ex) {
                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                }
                pauseSimulation = false;
            }
        });
        
        loadButton = new JButton("Load");
        loadButton.setEnabled(false);
        loadButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                pauseSimulation = true;
                try {
                    b.load();
                } catch (Exception ex) {
                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                }
                pauseSimulation = false;
            }
        });
        adminButtonPanel.add(loadButton);
        adminButtonPanel.add(saveButton);
        adminButtonPanel.add(editButton);
        adminButtonPanel.add(pauseButton);
        adminButtonPanel.add(startButton);
        
        adminUi.add(adminFormPanel);
        JLabel pplProbLabel = new JLabel("Probability (%) for People Entering", JLabel.CENTER);
        pplProbLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        adminUi.add(Box.createVerticalStrut(20));
        adminUi.add(pplProbLabel);
        adminUi.add(pplProbSlider);
        JLabel speedLabel = new JLabel("Speed (ms)", JLabel.CENTER);
        speedLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        adminUi.add(Box.createVerticalStrut(20));
        adminUi.add(speedLabel);
        adminUi.add(speedSlider);
        adminUi.add(Box.createVerticalStrut(260));
        adminUi.add(adminButtonPanel);

        tabBar.setSize(780, 580);
        tabBar.addTab("Admin", adminUi);
        this.add(tabBar);

        this.setVisible(true);
    }
    
/*

    private void saveButtonClicked() throws Exception {
        b.stop();
        b.save();
        b.start();
    }*/
    
  
    
    private void clean(){
//        elevatorUi = new JPanel();
        //floorUi = new JPanel();
        //floorGridLayout = new QGridLayout();
    }
    
    
    private void setAdminFields(boolean value){
        aNumOfFloorsLE.setEnabled(value);
        aEditFloorsButton.setEnabled(value);
        aNumOfElevatorsLE.setEnabled(value);
        aEditElevatorsButton.setEnabled(value);
        aNumOfPeopleLE.setEnabled(value);
    }

    public void actionPerformed(ActionEvent ae) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

